<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>闭包</title>
</head>
<body>
    <script>
        // 1. 实现一个对Array的求和。通常情况下，求和的函数是这样定义的
        function sum(arr) {
            return arr.reduce((x, y)=>(x + y));
        }

        // 但是，如果不需要立刻求和，而是在后面的代码中，根据需要再计算怎么办？
        // 可以不返回求和的结果，而是返回求和的函数！
        function lazy_sum(arr){
            var sum = function(){
                return arr.reduce((x,y)=>(x + y));
            }
            return sum;
        }
        var func = lazy_sum([1,2,3,4,5]);
        console.log(func());  // 15

        // 2. 闭包
        function count(){
            var arr2 = [];
            for(var i=1;i<=3;i++){  // 使用 let 声明时结果为  1  4  9
                arr2.push(function(){
                    return i * i;
                });
            }
            return arr2;
        }

        var results = count();
        var f1 = results[0];
        var f2 = results[1];
        var f3 = results[2];

        console.log(f1());  // 16
        console.log(f2());  // 16
        console.log(f3());  // 16

        // 3. 在没有class机制，只有函数的语言里，借助闭包，同样可以封装一个私有变量。
        //    我们用JavaScript创建一个计数器
        'use strict';

        function create_counter(initial) {
            var x = initial || 0;
            return {
                inc: function () {
                    x += 1;
                    return x;
                }
            }
        }

        var c1 = create_counter();
        console.log(c1.inc());
        console.log(c1.inc());
        console.log(c1.inc());
        
        var c2 = create_counter(10);
        console.log(c2.inc());
        console.log(c2.inc());
        console.log(c2.inc());

        function make_pow(n) {
            return function(x) { 
                return Math.pow(x, n);
            }
        }

        var pow2 = make_pow(2);
        var pow3 = make_pow(3);

        console.log(pow2(10));
        console.log(pow3(10));
    </script>
</body>
</html>